package com.ljd.gulimall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ljd.gulimall.product.entity.CategoryBrandRelationEntity;
import com.ljd.gulimall.product.service.CategoryBrandRelationService;
import com.ljd.gulimall.product.vo.Catelog2Vo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljd.common.utils.PageUtils;
import com.ljd.common.utils.Query;

import com.ljd.gulimall.product.dao.CategoryDao;
import com.ljd.gulimall.product.entity.CategoryEntity;
import com.ljd.gulimall.product.service.CategoryService;
import org.springframework.transaction.annotation.Transactional;


@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {

    @Autowired
    CategoryDao categoryDao;
    @Autowired
    CategoryBrandRelationService categoryBrandRelationService;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryEntity> page = this.page(
                new Query<CategoryEntity>().getPage(params),
                new QueryWrapper<CategoryEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<CategoryEntity> listWithTree() {
        List<CategoryEntity> categoryEntities = baseMapper.selectList(new QueryWrapper<>());

       // 过滤出顶级菜单
        List<CategoryEntity> topEntities = categoryEntities.stream().filter(categoryEntity -> Objects.equals(categoryEntity.getParentCid(), 0L))
                .collect(Collectors.toList());

        // 组装子菜单
        return topEntities.stream().peek(menu -> menu.setChildren(getChildrens(menu, categoryEntities)))
                .sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
                .collect(Collectors.toList());
    }

    @Override
    public void removeMenusByIds(Long[] catIds) {
        baseMapper.deleteBatchIds(Arrays.asList(catIds));
    }

    @Override
    public List<Long> findParentId(Long catelogId) {
        List<Long> ids = new ArrayList<>();
        List<Long> longs = findCatId(catelogId, ids);
        Collections.reverse(longs);
        return longs;
    }

    @Transactional
    @Override
    public void updateCascode(CategoryEntity category) {
        Long catId = category.getCatId();
        String name = category.getName();
        this.updateById(category);

        if(StringUtils.isNotBlank(name)) {
            CategoryBrandRelationEntity relation = new CategoryBrandRelationEntity();
//            relation.setCatelogId(catId);
            relation.setCatelogName(name);
            categoryBrandRelationService.update(relation, new UpdateWrapper<CategoryBrandRelationEntity>()
                    .eq("catelog_id", catId));
        }
    }

    @Override
    public Map<String, List<Catelog2Vo>> getCatlogJson() {
        List<CategoryEntity> categoryEntities = baseMapper.selectList(new LambdaQueryWrapper<CategoryEntity>().eq(CategoryEntity::getParentCid, '0'));
        // 一级分类id
        List<Long> firstIds = categoryEntities.stream().map(CategoryEntity::getCatId).collect(Collectors.toList());
        // 查询所有二级分类
        List<CategoryEntity> seconds = baseMapper.selectList(new LambdaQueryWrapper<CategoryEntity>().in(CategoryEntity::getParentCid, firstIds));
        List<Long> secondIds = seconds.stream().map(CategoryEntity::getCatId).collect(Collectors.toList());
        List<CategoryEntity> thirds = new ArrayList<>();
        if(seconds.size() > 0) {
            // 查询三级分类
            thirds = baseMapper.selectList(new LambdaQueryWrapper<CategoryEntity>().in(CategoryEntity::getParentCid, secondIds));

        }

        List<CategoryEntity> finalThirds = thirds;
        return categoryEntities.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {
            Long catId = v.getCatId();
            List<CategoryEntity> collect = seconds.stream().filter(categoryEntity -> Objects.equals(categoryEntity.getParentCid(), catId)).collect(Collectors.toList());
            return collect.stream().map(categoryEntity -> {
                Catelog2Vo catelog2Vo = new Catelog2Vo();
                catelog2Vo.setCatalog1Id(catId.toString());
                catelog2Vo.setId(categoryEntity.getCatId().toString());
                catelog2Vo.setName(categoryEntity.getName());
                if (finalThirds.size() > 0) {
                    List<CategoryEntity> entities = finalThirds.stream().filter(categoryEntity1 -> Objects.equals(categoryEntity1.getParentCid(), categoryEntity.getCatId())).collect(Collectors.toList());
                    List<Catelog2Vo.Catelog3Vo> catelog3Vos = entities.stream().map(categoryEntity1 -> {
                        Catelog2Vo.Catelog3Vo vo = new Catelog2Vo.Catelog3Vo();
                        vo.setId(categoryEntity1.getCatId().toString());
                        vo.setCatalog2Id(categoryEntity.getCatId().toString());
                        vo.setName(categoryEntity1.getName());
                        return vo;
                    }).collect(Collectors.toList());
                    catelog2Vo.setCatalog3List(catelog3Vos);
                }
                return catelog2Vo;
            }).collect(Collectors.toList());
        }));
    }

    /**
     * 收集分类id和夫分类id
     * @param catelogId
     * @param ids
     * @return
     */
    private List<Long> findCatId(Long catelogId, List<Long> ids) {
        ids.add(catelogId);
        CategoryEntity categoryEntity = baseMapper.selectById(catelogId);
        if(categoryEntity.getParentCid() != 0) {
            findCatId(categoryEntity.getParentCid(), ids);
        }
        return ids;
    }

    private List<CategoryEntity> getChildrens(CategoryEntity menu, List<CategoryEntity> categoryEntities) {
        return categoryEntities.stream().filter(categoryEntity -> Objects.equals(categoryEntity.getParentCid(), menu.getCatId()))
                .peek(categoryEntity -> categoryEntity.setChildren(getChildrens(categoryEntity, categoryEntities)))
                .sorted(Comparator.comparingInt(menu1 -> (menu1.getSort() == null ? 0 : menu1.getSort())))
                .collect(Collectors.toList());
    }

}